import java.io.File;
import java.io.FileOutputStream;

/*
 * Similarity between users based on number of common items rated.
 * More common items means more similar.
 */
public class ACI extends Scheduler implements Runnable {
	int start;
	int stop;
	byte[] BLOCK;
	int[] items;

	public ACI(int start, int stop) {
		this.start = start;
		this.stop = stop;
	}

	void writeBlock() {
		String FILE_NAME = BLOCK_PATH + start + ".bin";
		File out = new File(FILE_NAME);
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(out);
			fos.write(BLOCK);
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("Done writing: " + FILE_NAME + " @ "
				+ this.getClass());
	}

	@Override
	public void run() {
		int ilen = USERB[0].ilen;
		BLOCK = new byte[(stop - start) * ilen];

		int c = 0;
		for (int bUserID = start; bUserID < stop; bUserID++) {
			items = USERA[bUserID].items;
			for (int i = 0; i < ilen; i++) {
				int bItemID = items[i];
				byte pred = predict(bUserID, bItemID);
				BLOCK[c * ilen + i] = pred;
			}
			c++;
		}

		writeBlock();
	}

	byte predict(int userID, int itemID) {
		Item aItem = ITEMA[itemID];
		User mostSimilarUser = null;
		int currentSimilarity = 0;
		int bestSimilarity = 0;
		for (int historyUserId : aItem.users) {
			User historyUser = USERA[historyUserId];
			currentSimilarity = 0;
			for (int linkedItemId : historyUser.items) {
				if (USERA[userID].idToIdx.containsKey(Integer.valueOf(linkedItemId))) {
					currentSimilarity++;
				}
			}
			if (currentSimilarity > bestSimilarity) {
				bestSimilarity = currentSimilarity;
				mostSimilarUser = historyUser;
			}
		}
		if (mostSimilarUser == null)
			return 70;
		int idx = mostSimilarUser.idToIdx.get(Integer.valueOf(itemID));
		byte pred = mostSimilarUser.votes[idx];
		return pred;
	}

	boolean in(int itemID) {
		for (int i = 0; i < items.length; i++) {
			if (itemID == items[i]) {
				return true;
			}
			if (itemID > items[i])
				return false;
		}
		return false;
	}
}
